package icu.feigroup.domain.activity.service.trial.node;

import com.alibaba.fastjson.JSON;
import icu.feigroup.domain.activity.model.entity.MarketProductEntity;
import icu.feigroup.domain.activity.model.entity.TrialBalanceEntity;
import icu.feigroup.domain.activity.model.valobj.GroupActivityDiscountVO;
import icu.feigroup.domain.activity.model.valobj.SkuVO;
import icu.feigroup.domain.activity.service.discount.IDiscountCalculateService;
import icu.feigroup.domain.activity.service.trial.AbstractGroupBuyMarketSupport;
import icu.feigroup.domain.activity.service.trial.factory.DefaultActivityStrategyFactory;
import icu.feigroup.domain.activity.service.trial.thread.QueryGroupActivityDiscountVOThreadTask;
import icu.feigroup.domain.activity.service.trial.thread.QuerySkuVOFromDBThreadTask;
import icu.feigroup.types.design.framwork.tree.StrategyHandler;
import icu.feigroup.types.enums.ResponseCode;
import icu.feigroup.types.exception.AppException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Map;
import java.util.concurrent.*;

/**
 * projectName:icu.feigroup.domain.activity.service.trial.node
 *
 * @author 飞
 * @since 2025/2/19 11:41
 * description:
 */
@Slf4j
@Service
public class MarketNode extends AbstractGroupBuyMarketSupport<MarketProductEntity, DefaultActivityStrategyFactory.DynamicContext, TrialBalanceEntity> {
    @Resource
    private ThreadPoolExecutor threadPoolExecutor;
    @Resource
    private TagNode tagNode;
    @Resource
    private ErrNode errNode;

    @Resource
    private Map<String, IDiscountCalculateService> discountCalculateServiceMap;

    @Override
    protected void multiThread(MarketProductEntity requestParameter, DefaultActivityStrategyFactory.DynamicContext dynamicContext) throws ExecutionException, InterruptedException, TimeoutException {
        // 异步查询活动配置
        QueryGroupActivityDiscountVOThreadTask queryGroupActivityDiscountVOThreadTask = new QueryGroupActivityDiscountVOThreadTask(requestParameter.getActivityId(), requestParameter.getSource(), requestParameter.getChannel(), requestParameter.getGoodsId(),repository);
        FutureTask<GroupActivityDiscountVO> groupActivityDiscountVOFutureTask = new FutureTask<>(queryGroupActivityDiscountVOThreadTask);
        threadPoolExecutor.execute(groupActivityDiscountVOFutureTask);

        // 异步查询商品信息 - 在实际生产中，商品有同步库或者调用接口查询。这里暂时使用DB方式查询。
        QuerySkuVOFromDBThreadTask querySkuVOFromDBThreadTask = new QuerySkuVOFromDBThreadTask(requestParameter.getGoodsId(), repository);
        FutureTask<SkuVO> skuVOFutureTask = new FutureTask<>(querySkuVOFromDBThreadTask);
        threadPoolExecutor.execute(skuVOFutureTask);

        // 写入上下文 - 对于一些复杂场景，获取数据的操作，有时候会在下N个节点获取，这样前置查询数据，可以提高接口响应效率
        dynamicContext.setGroupActivityDiscountVO(groupActivityDiscountVOFutureTask.get(timeout, TimeUnit.MINUTES));
        dynamicContext.setSkuVO(skuVOFutureTask.get(timeout, TimeUnit.MINUTES));

        log.info("拼团商品查询试算服务-MarketNode userId:{} 异步线程加载数据「GroupBuyActivityDiscountVO、SkuVO」完成", requestParameter.getUserId());
    }

    @Override
    public TrialBalanceEntity doApply(MarketProductEntity requestParameter, DefaultActivityStrategyFactory.DynamicContext dynamicContext) throws Exception {
        log.info("拼团商品查询试算服务-MarketNode userId:{} requestParameter:{}", requestParameter.getUserId(), JSON.toJSONString(requestParameter));

        GroupActivityDiscountVO groupActivityDiscountVO = dynamicContext.getGroupActivityDiscountVO();
        if (groupActivityDiscountVO==null) return router(requestParameter,dynamicContext);

        GroupActivityDiscountVO.GroupDiscount groupDiscount = groupActivityDiscountVO.getGroupDiscount();
        SkuVO skuVO = dynamicContext.getSkuVO();

        if (groupDiscount == null ||skuVO == null) return router(requestParameter,dynamicContext);
        //拼团优惠试算
        IDiscountCalculateService discountCalculateService = discountCalculateServiceMap.get(groupDiscount.getMarketPlan());
        if (discountCalculateService==null){
            throw new AppException(ResponseCode.E001.getCode(),ResponseCode.E001.getInfo());
        }
        BigDecimal payPrice = discountCalculateService.calculate(requestParameter.getUserId(), skuVO.getOriginalPrice(), groupDiscount);
        //写入上下文
        dynamicContext.setDeductionPrice(skuVO.getOriginalPrice().subtract(payPrice));
        dynamicContext.setPayPrice(payPrice);
        return router(requestParameter, dynamicContext);
    }

    @Override
    public StrategyHandler<MarketProductEntity, DefaultActivityStrategyFactory.DynamicContext, TrialBalanceEntity> get(MarketProductEntity requestParameter, DefaultActivityStrategyFactory.DynamicContext dynamicContext) throws Exception {
        if (dynamicContext.getGroupActivityDiscountVO()==null ||
                dynamicContext.getSkuVO()==null ||
                dynamicContext.getDeductionPrice()==null){
            return errNode;
        }
        return tagNode;
    }
}
